/**
 * 
 */
package foo;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringReader;
import java.net.InetAddress;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.terukusu.ahoomsgr.ChallengeResponseUtility;
import org.terukusu.ahoomsgr.Constants;
import org.terukusu.ahoomsgr.YmsgException;
import org.terukusu.ahoomsgr.YmsgPacket;
import org.terukusu.util.HttpResponse;
import org.terukusu.util.NetUtils;
import org.terukusu.util.Utils;

import android.util.Log;

/**
 * Yahoo!Japan 版の YMSG プロトコルを試してみるためのクラスです。 
 * @author Teruhiko Kusunoki&lt;<a
 *         href="teru.kusu@gmail.com">teru.kusu@gmail.com</a>&gt;
 * 
 */
public class Hoge {
	public static void main(String[] args) throws Exception {
		String url1 = "http://cs.yahoo.co.jp/capacity";
		String url2 = "https://login.yahoo.co.jp/config/pwtoken_get";
		String url3 = "https://login.yahoo.co.jp/config/pwtoken_login";
		String user = args[0];
		String password = args[1];
		HttpResponse res = NetUtils.httpGet(url1, null, null, null, false);
		String bodyStr = new String(res.getBody(), "8859_1");
		Log.v(Constants.LOG_TAG, bodyStr);
		
		Matcher m = Pattern.compile("CS_IP_ADDRESS=([\\d\\.]*)").matcher(bodyStr);
		m.find();
		String serverIp = m.group(1);

		Log.v(Constants.LOG_TAG, "serverIp: " + serverIp);
		
		YmsgPacket outPacket = new YmsgPacket();
		outPacket.setProtocolVersion(0x10);
		outPacket.setVendorId(0x64);
		outPacket.setService(0x57);
		outPacket.setStatus(0);
		outPacket.addValue("1", user);
		
		OutputStream os;
		InputStream is;
		
		InetAddress addr = InetAddress.getByName(serverIp);
		Socket sock = new Socket(addr, 5050);

		os = sock.getOutputStream();
		outPacket.writeTo(os);

		is = sock.getInputStream();
		YmsgPacket inPacket = new YmsgPacket(is);
		
//		sock.close();

		String challenge = inPacket.getValueAsString("94");
		Integer sessionId = inPacket.getSessionId();
		
		Map<String, String> params = new HashMap<String, String>();
		params.put("src", "ymsgr");
		params.put("ts", "");
		params.put("login", user);
		params.put("passwd", password);
		params.put("chal", challenge);
		HttpResponse res2 = NetUtils.httpGet(url2, params, null, null, true);

		String res2BodyStr = new String(res2.getBody(), "8859_1");
		Log.v(Constants.LOG_TAG, "res2BodyStr: " + res2BodyStr);
		
		String line = null;
		BufferedReader br = new BufferedReader(new StringReader(res2BodyStr), 64);
		line = br.readLine();
		
		if (line == null || !"0".equals(line)) {
			throw new YmsgException("status invalid: status=" + line);
		}

		line = br.readLine();
		String ymsgr = line.substring(line.indexOf('=') + 1);
		Log.v(Constants.LOG_TAG, "ymsgr: " + ymsgr);

		line = br.readLine();
		String partnerId = line.substring(line.indexOf('=') + 1);
		Log.v(Constants.LOG_TAG, "partnerId: " + partnerId);
		
		br.close();
		
		params.clear();
		params.put("src", "ymsgr");
		params.put("ts", "");
		params.put("token", ymsgr);
		Log.v(Constants.LOG_TAG, Utils.hexDump(ymsgr.getBytes()));
		
		HttpResponse res3 = NetUtils.httpGet(url3, params, null, null, true);
		String res3BodyStr = new String(res3.getBody(), "8859_1");
		Log.v(Constants.LOG_TAG, "res3Body: " + Utils.hexDump(res3.getBody()));

		br = new BufferedReader(new StringReader(res3BodyStr));
		
		line = br.readLine();
		
		if (line == null || !"0".equals(line)) {
			throw new YmsgException("status invalid: status=" + line);
		}

		line = br.readLine();
		String crumb = line.split("=")[1];
		Log.v(Constants.LOG_TAG, "crumb: " + crumb);
		
		line = br.readLine();
		String yCookie = line.substring(line.indexOf('=') + 1, line.indexOf(';'));
		Log.v(Constants.LOG_TAG, "yCookie: " + yCookie);
		
		line = br.readLine();
		String tCookie = line.substring(line.indexOf('=') + 1, line.indexOf(';'));
		Log.v(Constants.LOG_TAG, "tCookie: " + tCookie);

		String crypt = crumb + challenge;
		byte[] md5 = ChallengeResponseUtility.md5(crypt);
		String y64str = ChallengeResponseUtility.yahoo64(md5);
		
		YmsgPacket outPacket2 = new YmsgPacket();
		outPacket2.setProtocolVersion(0x10);
		outPacket2.setVendorId(0x64);
		outPacket2.setService(0x54);
		outPacket2.setStatus(0);
		outPacket2.addValue("1", user);
		outPacket2.addValue("0", user);
		outPacket2.addValue("277", yCookie);
		outPacket2.addValue("278", tCookie);
		outPacket2.addValue("307", y64str);
		outPacket2.addValue("244", "4186047");
		outPacket2.addValue("2", user);
		outPacket2.addValue("2", "1");
		outPacket2.addValue("98", "ja");
		outPacket2.addValue("135", "9.0.0.1727");
		
		outPacket2.writeTo(os);

		YmsgPacket inPacket3 = new YmsgPacket(is);
		Log.v(Constants.LOG_TAG, inPacket3.toString());
		
		YmsgPacket inPacket4 = new YmsgPacket(is);
		Log.v(Constants.LOG_TAG, inPacket4.toString());
		YmsgPacket inPacket5 = new YmsgPacket(is);
		Log.v(Constants.LOG_TAG, inPacket5.toString());
		YmsgPacket inPacket6 = new YmsgPacket(is);
		Log.v(Constants.LOG_TAG, inPacket6.toString());
		YmsgPacket inPacket7 = new YmsgPacket(is);
		Log.v(Constants.LOG_TAG, inPacket7.toString());
		YmsgPacket inPacket8 = new YmsgPacket(is);
		Log.v(Constants.LOG_TAG, inPacket8.toString());
		
		YmsgPacket outPacket4 = new YmsgPacket();
		outPacket4.setProtocolVersion(0x10);
		outPacket4.setVendorId(0x64);
		outPacket4.setService(0x04);
		outPacket4.setStatus(0x0C);
		outPacket4.setSessionId(sessionId);
		Log.v(Constants.LOG_TAG, "YMSG write: " + outPacket4);

		YmsgPacket outPacket3 = new YmsgPacket();
		outPacket3.setProtocolVersion(0x10);
		outPacket3.setVendorId(0x64);
		outPacket3.setService(0x06);
		outPacket3.setStatus(1);
		outPacket3.setSessionId(sessionId);
		outPacket3.addValue("0", user);
		outPacket3.addValue("1", user);
		outPacket3.addValue("5", "foobar_x1");
		outPacket3.addValue("14", "こんにちは。自作メッセンジャーからです。");
		outPacket3.writeTo(os);
		
		Log.v(Constants.LOG_TAG, "YMSG write: " + outPacket3);

		YmsgPacket tmpPacket = new YmsgPacket();
		while (true) {
			try {
				tmpPacket.load(is);
				Log.v(Constants.LOG_TAG, "YMSG received: " + tmpPacket);
				if (tmpPacket.getService() == 0x7d1) {
					is.close();
					sock.close();
					break;
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

}
